package com.qdev.apps.core.webwork.interceptor;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.opensymphony.xwork.ActionInvocation;
import com.opensymphony.xwork.interceptor.Interceptor;
import com.opensymphony.xwork.util.OgnlValueStack;

/**
 * a simple exception handler interceptor, catch any uncaught exceptions, log
 * and return to global "exception" result.
 * 
 * @author Quake Wang
 * @since 2005-1-20
 * @version $Revision: 1.3 $
 */
public class ExceptionInterceptor implements Interceptor {
    private static final Log log = LogFactory.getLog(ExceptionInterceptor.class);

    public static final String EXCEPTION = "exception";

    public void destroy() {
        // TODO Auto-generated method stub

    }

    public void init() {
        // TODO Auto-generated method stub

    }

    public String intercept(ActionInvocation invocation) throws Exception {
        try {
            return invocation.invoke();
        } catch (Exception e) {
            String message = "Caught exception while invoking action: " + invocation.getAction();
            log.error(message, e);
            log.info("Session info:"+invocation.getInvocationContext().getSession());
            log.info("Value stack info when exception:" + getParameters(invocation.getStack()));
            StringWriter sw = new StringWriter();
            e.printStackTrace(new PrintWriter(sw));
            invocation.getInvocationContext().put("_exception_string_", sw.toString());
            return EXCEPTION;
        }
    }

    private String getParameters(OgnlValueStack stack) {
        String result = "";
        try {
            Map map = (Map) stack.getContext().get("parameters");
            if (map != null) {
                Iterator itr = map.keySet().iterator();
                while (itr.hasNext()) {
                    String key = (String) itr.next();
                    String value = "";
                    Object values[] = (Object[]) map.get(key);
                    for (int i = 0; values != null && i < values.length; i++) {
                        value += (values[i] != null) ? values[i].toString() : null;
                    }
                    result += key + "={" + value + "};\n";
                }
            }
        } catch (Exception ex) {
            log.error("Exception when getParameters:", ex);
        }
        return result;
    }
}